package cn.iocoder.yudao.module.system.dal.mysql.userbehavior;

import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.system.dal.dataobject.userbehavior.UserBehaviorDetailDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 用户行为详情 Mapper
 *
 * @author 系统开发团队
 */
@Mapper
public interface UserBehaviorDetailMapper extends BaseMapperX<UserBehaviorDetailDO> {

    /**
     * 根据用户ID和时间范围查询行为记录
     */
    default List<UserBehaviorDetailDO> selectByUserIdAndTimeRange(Long userId, LocalDateTime startTime, LocalDateTime endTime) {
        return selectList(new LambdaQueryWrapperX<UserBehaviorDetailDO>()
                .eq(UserBehaviorDetailDO::getUserId, userId)
                .between(UserBehaviorDetailDO::getCreateTime, startTime, endTime)
                .orderByDesc(UserBehaviorDetailDO::getCreateTime));
    }

    /**
     * 根据会话ID查询行为记录
     */
    default List<UserBehaviorDetailDO> selectBySessionId(String sessionId) {
        return selectList(new LambdaQueryWrapperX<UserBehaviorDetailDO>()
                .eq(UserBehaviorDetailDO::getSessionId, sessionId)
                .orderByAsc(UserBehaviorDetailDO::getCreateTime));
    }

    /**
     * 根据行为类型和时间范围查询
     */
    default List<UserBehaviorDetailDO> selectByBehaviorTypeAndTimeRange(Integer behaviorType, 
                                                                         LocalDateTime startTime, 
                                                                         LocalDateTime endTime) {
        return selectList(new LambdaQueryWrapperX<UserBehaviorDetailDO>()
                .eq(UserBehaviorDetailDO::getBehaviorType, behaviorType)
                .between(UserBehaviorDetailDO::getCreateTime, startTime, endTime)
                .orderByDesc(UserBehaviorDetailDO::getCreateTime));
    }

    /**
     * 统计用户行为次数
     */
    default Long countUserBehavior(Long userId, Integer behaviorType, LocalDateTime startTime, LocalDateTime endTime) {
        return selectCount(new LambdaQueryWrapperX<UserBehaviorDetailDO>()
                .eq(userId != null, UserBehaviorDetailDO::getUserId, userId)
                .eq(behaviorType != null, UserBehaviorDetailDO::getBehaviorType, behaviorType)
                .between(startTime != null && endTime != null, UserBehaviorDetailDO::getCreateTime, startTime, endTime));
    }

    /**
     * 统计功能使用次数
     */
    default Long countFeatureUsage(String behaviorAction, LocalDateTime startTime, LocalDateTime endTime) {
        return selectCount(new LambdaQueryWrapperX<UserBehaviorDetailDO>()
                .eq(UserBehaviorDetailDO::getBehaviorAction, behaviorAction)
                .between(UserBehaviorDetailDO::getCreateTime, startTime, endTime));
    }

    /**
     * 统计功能使用用户数
     */
    default Long countFeatureUsers(String behaviorAction, LocalDateTime startTime, LocalDateTime endTime) {
        // 这里需要使用原生SQL来实现去重统计
        return selectCount(new LambdaQueryWrapperX<UserBehaviorDetailDO>()
                .eq(UserBehaviorDetailDO::getBehaviorAction, behaviorAction)
                .between(UserBehaviorDetailDO::getCreateTime, startTime, endTime)
                .groupBy(UserBehaviorDetailDO::getUserId));
    }

    /**
     * 统计用户类型分布
     */
    default List<Map<String, Object>> countUserTypeDistribution(LocalDateTime startTime, LocalDateTime endTime) {
        // 需要使用原生SQL实现分组统计
        return selectMaps(new LambdaQueryWrapperX<UserBehaviorDetailDO>()
                .select(UserBehaviorDetailDO::getUserType)
                .between(UserBehaviorDetailDO::getCreateTime, startTime, endTime)
                .groupBy(UserBehaviorDetailDO::getUserType)
                .last("SELECT user_type, COUNT(DISTINCT user_id) as userCount"));
    }

    /**
     * 统计设备类型分布
     */
    default List<Map<String, Object>> countDeviceTypeDistribution(LocalDateTime startTime, LocalDateTime endTime) {
        return selectMaps(new LambdaQueryWrapperX<UserBehaviorDetailDO>()
                .select(UserBehaviorDetailDO::getDeviceType)
                .between(UserBehaviorDetailDO::getCreateTime, startTime, endTime)
                .groupBy(UserBehaviorDetailDO::getDeviceType)
                .last("SELECT device_type, COUNT(DISTINCT user_id) as userCount"));
    }

    /**
     * 统计地区分布
     */
    default List<Map<String, Object>> countRegionDistribution(LocalDateTime startTime, LocalDateTime endTime) {
        return selectMaps(new LambdaQueryWrapperX<UserBehaviorDetailDO>()
                .select(UserBehaviorDetailDO::getRegion)
                .between(UserBehaviorDetailDO::getCreateTime, startTime, endTime)
                .isNotNull(UserBehaviorDetailDO::getRegion)
                .groupBy(UserBehaviorDetailDO::getRegion)
                .last("SELECT region, COUNT(DISTINCT user_id) as userCount ORDER BY userCount DESC LIMIT 10"));
    }

    /**
     * 查询高活跃用户
     */
    default List<UserBehaviorDetailDO> selectHighActiveUsers(LocalDateTime startTime, LocalDateTime endTime, 
                                                              Integer minBehaviorCount) {
        // 需要使用原生SQL实现
        return selectList(new LambdaQueryWrapperX<UserBehaviorDetailDO>()
                .between(UserBehaviorDetailDO::getCreateTime, startTime, endTime)
                .groupBy(UserBehaviorDetailDO::getUserId)
                .having("COUNT(*) >= " + minBehaviorCount)
                .last("ORDER BY COUNT(*) DESC"));
    }

    /**
     * 查询用户会话列表
     */
    default List<UserBehaviorDetailDO> selectUserSessions(Long userId, LocalDateTime startTime, LocalDateTime endTime) {
        return selectList(new LambdaQueryWrapperX<UserBehaviorDetailDO>()
                .eq(UserBehaviorDetailDO::getUserId, userId)
                .between(UserBehaviorDetailDO::getCreateTime, startTime, endTime)
                .groupBy(UserBehaviorDetailDO::getSessionId)
                .orderByDesc(UserBehaviorDetailDO::getCreateTime));
    }

    /**
     * 统计平均会话时长
     */
    default Double selectAvgSessionDuration(LocalDateTime startTime, LocalDateTime endTime) {
        // 需要使用原生SQL实现复杂统计
        return 0.0; // 占位实现
    }

    /**
     * 统计平均行为时长
     */
    default Double selectAvgBehaviorDuration(Integer behaviorType, LocalDateTime startTime, LocalDateTime endTime) {
        // 需要使用原生SQL实现
        return 0.0; // 占位实现
    }

    /**
     * 删除过期数据
     */
    default int deleteExpiredData(LocalDateTime beforeTime) {
        return delete(new LambdaQueryWrapperX<UserBehaviorDetailDO>()
                .lt(UserBehaviorDetailDO::getCreateTime, beforeTime));
    }

    /**
     * 分页查询用户行为详情
     */
    default PageResult<UserBehaviorDetailDO> selectPage(Long userId, Integer behaviorType, Integer userType,
                                                         LocalDateTime startTime, LocalDateTime endTime,
                                                         String sessionId, Integer behaviorResult,
                                                         int pageNo, int pageSize) {
        PageParam pageParam = new PageParam();
        pageParam.setPageNo(pageNo);
        pageParam.setPageSize(pageSize);
        return selectPage(pageParam, new LambdaQueryWrapperX<UserBehaviorDetailDO>()
                .eq(userId != null, UserBehaviorDetailDO::getUserId, userId)
                .eq(behaviorType != null, UserBehaviorDetailDO::getBehaviorType, behaviorType)
                .eq(userType != null, UserBehaviorDetailDO::getUserType, userType)
                .eq(sessionId != null, UserBehaviorDetailDO::getSessionId, sessionId)
                .eq(behaviorResult != null, UserBehaviorDetailDO::getBehaviorResult, behaviorResult)
                .between(startTime != null && endTime != null, UserBehaviorDetailDO::getCreateTime, startTime, endTime)
                .orderByDesc(UserBehaviorDetailDO::getCreateTime));
    }

    /**
     * 查询用户最近行为
     */
    default List<UserBehaviorDetailDO> selectRecentBehaviors(Long userId, Integer limit) {
        return selectList(new LambdaQueryWrapperX<UserBehaviorDetailDO>()
                .eq(UserBehaviorDetailDO::getUserId, userId)
                .orderByDesc(UserBehaviorDetailDO::getCreateTime)
                .last("LIMIT " + (limit != null ? limit : 10)));
    }

    /**
     * 查询热门功能
     */
    default List<Map<String, Object>> selectPopularFeatures(LocalDateTime startTime, LocalDateTime endTime, Integer limit) {
        return selectMaps(new LambdaQueryWrapperX<UserBehaviorDetailDO>()
                .select(UserBehaviorDetailDO::getBehaviorAction)
                .between(UserBehaviorDetailDO::getCreateTime, startTime, endTime)
                .eq(UserBehaviorDetailDO::getBehaviorType, UserBehaviorDetailDO.BEHAVIOR_TYPE_FEATURE_USAGE)
                .groupBy(UserBehaviorDetailDO::getBehaviorAction)
                .last("SELECT behavior_action, COUNT(*) as usageCount, COUNT(DISTINCT user_id) as userCount ORDER BY usageCount DESC LIMIT " + (limit != null ? limit : 10)));
    }

    /**
     * 查询错误行为统计
     */
    default List<Map<String, Object>> selectErrorBehaviorStats(LocalDateTime startTime, LocalDateTime endTime) {
        return selectMaps(new LambdaQueryWrapperX<UserBehaviorDetailDO>()
                .select(UserBehaviorDetailDO::getBehaviorAction)
                .between(UserBehaviorDetailDO::getCreateTime, startTime, endTime)
                .eq(UserBehaviorDetailDO::getBehaviorResult, UserBehaviorDetailDO.BEHAVIOR_RESULT_FAILURE)
                .groupBy(UserBehaviorDetailDO::getBehaviorAction)
                .last("SELECT behavior_action, COUNT(*) as errorCount ORDER BY errorCount DESC"));
    }
}